home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / atre27.exe / ATREE_27 / OCRDEMO2 / OCRTRAIN.CPP < prev    next >
C/C++ Source or Header  |  1992-08-01  |  15KB  |  567 lines

  1. /*****************************************************************************
  2.  ****                                                                     ****
  3.  **** ocrtrain.cpp                                                        ****
  4.  ****                                                                     ****
  5.  **** atree release 2.7 for Windows                                       ****
  6.  **** Adaptive Logic Network (ALN) simulation program.                    ****
  7.  **** Copyright (C) M. Thomas, N. Sanche, W.W. Armstrong 1991, 1992       ****
  8.  ****                                                                                       ****
  9.  **** License:                                                            ****
  10.  **** A royalty-free license is granted for the use of this software for  ****
  11.  **** NON_COMMERCIAL PURPOSES ONLY. The software may be copied and/or     ****
  12.  **** modified provided this notice appears in its entirety and unchanged ****
  13.  **** in all derived source programs.  Persons modifying the code are     ****
  14.  **** requested to state the date, the changes made and who made them     ****
  15.  **** in the modification history.                                        ****
  16.  ****                                                                     ****
  17.  **** Patent License:                                                     ****
  18.  **** The use of a digital circuit which transmits a signal indicating    ****
  19.  **** heuristic responsibility is protected by U. S. Patent 3,934,231     ****
  20.  **** and others assigned to Dendronic Decisions Limited of Edmonton,     ****
  21.  **** W. W. Armstrong, President.  A royalty-free license is granted      ****
  22.  **** by the company to use this patent for NON_COMMERCIAL PURPOSES to    ****
  23.  **** adapt logic trees using this program and its modifications.         ****
  24.  ****                                                                     ****
  25.  **** Limited Warranty:                                                   ****
  26.  **** This software is provided "as is" without warranty of any kind,     ****
  27.  **** either expressed or implied, including, but not limited to, the     ****
  28.  **** implied warrantees of merchantability and fitness for a particular  ****
  29.  **** purpose.  The entire risk as to the quality and performance of the  ****
  30.  **** program is with the user.  Neither the authors, nor the             ****
  31.  **** University of Alberta, its officers, agents, servants or employees  ****
  32.  **** shall be liable or responsible in any way for any damage to         ****
  33.  **** property or direct personal or consequential injury of any nature   ****
  34.  **** whatsoever that may be suffered or sustained by any licensee, user  ****
  35.  **** or any other party as a consequence of the use or disposition of    ****
  36.  **** this software.                                                      ****
  37.  **** Modification history:                                               ****
  38.  ****                                                                     ****
  39.  **** 92.04.27 atree v2.5 for Windows, M. Thomas                          ****
  40.  **** 92.03.07 Release 2.6, Monroe Thomas, Neal Sanche                    ****
  41.  **** 92.01.08 Release 2.7, Monroe Thomas, Neal Sanche                    ****
  42.  ****                                                                     ****
  43.  *****************************************************************************/
  44.  
  45. // ocrtrain.cpp
  46.  
  47. #include "ocr.h"
  48. #include <edit.h>
  49.  
  50. void
  51. TOcr::translate(HBITMAP hbm1, int dx, int dy)
  52. {
  53.     HBITMAP hbm2;
  54.     BITMAP bm;
  55.     HDC hdc1 = CreateCompatibleDC(NULL);
  56.     HDC hdc2 = CreateCompatibleDC(NULL);
  57.     GetObject(hbm1, sizeof(BITMAP), (LPSTR)&bm);
  58.  
  59.     hbm2 = CreateBitmap(bm.bmWidth * 2, bm.bmHeight * 2, bm.bmPlanes,
  60.                                          bm.bmBitsPixel, NULL);
  61.  
  62.     SelectObject(hdc1, hbm1);
  63.     SelectObject(hdc2, hbm2);
  64.  
  65.     SetStretchBltMode(hdc1, COLORONCOLOR);
  66.     SetStretchBltMode(hdc2, WHITEONBLACK);
  67.  
  68.     StretchBlt(hdc2, 0 + dx, 0 + dy,
  69.                          bm.bmWidth * 2,
  70.                          bm.bmHeight * 2,
  71.                          hdc1, 0, 0,
  72.                          bm.bmWidth,
  73.                          bm.bmHeight,
  74.                          SRCCOPY);
  75.     StretchBlt(hdc1, 0, 0,
  76.                          bm.bmWidth,
  77.                          bm.bmHeight,
  78.                          hdc2, 0, 0,
  79.                          bm.bmWidth * 2,
  80.                          bm.bmHeight * 2,
  81.                          SRCCOPY);
  82.  
  83.     DeleteDC(hdc1);
  84.     DeleteDC(hdc2);
  85.     DeleteObject(hbm2);
  86. }
  87.  
  88. #define NOISEBITS (16*30)
  89.  
  90. void
  91. TOcr::train(TrainStruct& ts)
  92. {
  93.     PTDialog TrainSet;
  94.     PTBStatic TrainPct;
  95.     LPBIT_VEC training_set;
  96.     LPBIT_VEC desired;
  97.     char des[1];
  98.     WORD numsamples =  ts.numsamples * 5;
  99.     float numdone = 0;
  100.     char szBuffer[8];
  101.     PTBitmap A[27];
  102.     PTBitmap L[27];
  103.     PTBitmap N[27];
  104.  
  105.     WORD width = LetterBitmap->GetBytes();    //in bytes
  106.     WORD length = width * 8;
  107.     WORD numbits = .95 * length;
  108.  
  109.     if (LetterBitmap->GetPlanes() != 1)
  110.     {
  111.         BWCCMessageBox(HWindow, "Need monochrome bitmaps!", "OCR Train", MB_OK);
  112.         exit(0);
  113.     }
  114.  
  115.     TrainSet = new TDialog(this, OCR_TRAINSET);
  116.     TrainPct = new TBStatic(TrainSet, OCR_TRAINPCT, 8);
  117.     GetApplication()->MakeWindow(TrainSet);
  118.  
  119.     UpdateWindow(HWindow);
  120.  
  121.     HCURSOR hcursor = LoadCursor(NULL, IDC_WAIT);
  122.     hcursor = SetCursor(hcursor);
  123.  
  124.     for (WORD i = 0; i < 3; i++)
  125.     {
  126.         A[i] = new TBitmap(ts.bitmaps[0]);
  127.         L[i] = new TBitmap(ts.bitmaps[1]);
  128.         N[i] = new TBitmap(ts.bitmaps[2]);
  129.     }
  130.  
  131.     A[1]->Rotate(ts.maxrotation);
  132.     L[1]->Rotate(ts.maxrotation);
  133.     N[1]->Rotate(ts.maxrotation);
  134.  
  135.     A[2]->Rotate(-ts.maxrotation);
  136.     L[2]->Rotate(-ts.maxrotation);
  137.     N[2]->Rotate(-ts.maxrotation);
  138.  
  139.     for (i = 3; i < 27; i++)
  140.     {
  141.         A[i] = new TBitmap(A[i % 3]->GetBitmap());
  142.         L[i] = new TBitmap(L[i % 3]->GetBitmap());
  143.         N[i] = new TBitmap(N[i % 3]->GetBitmap());
  144.     }
  145.  
  146.     for (i = 3; i < 24; i++)
  147.     {
  148.         int dx, dy;
  149.         if (i < 6)
  150.         {
  151.             dx = 0; dy = 1;
  152.         }
  153.         if (i < 9)
  154.         {
  155.             dx = 1; dy = 0;
  156.         }
  157.         if (i < 12)
  158.         {
  159.             dx = 1; dy = 1;
  160.         }
  161.         if (i < 15)
  162.         {
  163.             dx = 0; dy = -1;
  164.         }
  165.         if (i < 18)
  166.         {
  167.             dx = -1; dy = 0;
  168.         }
  169.         if (i < 21)
  170.         {
  171.             dx = -1; dy = -1;
  172.         }
  173.         if (i < 24)
  174.         {
  175.             dx = -1; dy = 1;
  176.         }
  177.         if (i < 27)
  178.         {
  179.             dx = 1; dy = -1;
  180.         }
  181.         translate(A[i]->GetBitmap(), dx, dy);
  182.         translate(L[i]->GetBitmap(), dx, dy);
  183.         translate(N[i]->GetBitmap(), dx, dy);
  184.     }
  185.  
  186.     training_set = (LPBIT_VEC)farmalloc(sizeof(bit_vec) * numsamples);
  187.     MEMCHECK(training_set);
  188.  
  189.     desired = (LPBIT_VEC)farmalloc(sizeof(bit_vec) * numsamples);
  190.     MEMCHECK(desired);
  191.  
  192.     for (i = 0; i < numsamples; i++)
  193.     {
  194.         training_set[i].len = length;
  195.         training_set[i].bv = (LPSTR)farmalloc(width);
  196.         desired[i].bv = NULL;
  197.     }
  198.  
  199.     SetCursor(hcursor);
  200.  
  201.     UpdateWindow(HWindow);
  202.  
  203.     // Grab a good A
  204.     A[0]->GetBits(training_set[0].bv);
  205.     des[0] = 1;        // want 1 output
  206.     desired[0] = *(bv_pack(des,1));
  207.  
  208.     // Grab a good L
  209.     L[0]->GetBits(training_set[1].bv);
  210.     des[0] = 0;        // want 0 output
  211.     desired[1] = *(bv_pack(des,1));
  212.  
  213.     // Grab a good N
  214.     N[0]->GetBits(training_set[2].bv);
  215.     des[0] = 0;        // want 0 output
  216.     desired[2] = *(bv_pack(des,1));
  217.  
  218.     numdone += 3;
  219.  
  220.     // create training data
  221.     for (i = 1; i < ts.numsamples; i++)
  222.     {
  223.         /* allow multitasking during long loop! */
  224.         Windows_Interrupt(100);
  225.  
  226.         if (shutdown || stop) break;
  227.  
  228.         // Get an A
  229.         A[random(27)]->GetBits(training_set[i*3].bv);
  230.         des[0] = 1;        // want 1 output
  231.         desired[i*3] = *(bv_pack(des,1));
  232.  
  233.         for (WORD j = 0; j < numbits; j++)
  234.         {
  235.             bv_set(RANDOM(length), &(training_set[i*3]), RANDOM(2));
  236.         }
  237.  
  238.         if (shutdown || stop) break;
  239.  
  240.         // Get a L
  241.         L[random(27)]->GetBits(training_set[i*3 + 1].bv);
  242.         des[0] = 0;        // want 0 output
  243.         desired[(i*3) + 1] = *(bv_pack(des,1));
  244.  
  245.         for (j = 0; j < numbits; j++)
  246.         {
  247.             bv_set(RANDOM(length), &(training_set[i*3 + 1]), RANDOM(2));
  248.         }
  249.  
  250.         if (shutdown || stop) break;
  251.  
  252.         // Get a N
  253.         N[random(27)]->GetBits(training_set[i*3 + 2].bv);
  254.         des[0] = 0;        // want 0 output
  255.         desired[(i*3) + 2] = *(bv_pack(des,1));
  256.  
  257.         for (j = 0; j < numbits; j++)
  258.         {
  259.             bv_set(RANDOM(length), &(training_set[i*3 + 2]), RANDOM(2));
  260.         }
  261.         numdone += 3;
  262.         sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
  263.         TrainPct->SetText(szBuffer);
  264.     }
  265.  
  266.     // Now reinforce on a white frame
  267.     if (!(shutdown || stop))
  268.     {
  269.         A[0]->GetBits(training_set[ts.numsamples * 3].bv);
  270.         des[0] = 0;
  271.         desired[ts.numsamples * 3] = *(bv_pack(des,1));
  272.  
  273.         for (WORD j = 0; j < length; j++)
  274.         {
  275.             bv_set(j, &(training_set[ts.numsamples * 3]), 1);
  276.         }
  277.         numdone++;
  278.     }
  279.  
  280.     for (i = (ts.numsamples * 3) + 1; i < (ts.numsamples * 4); i++)
  281.     {
  282.         if (shutdown || stop) break;
  283.  
  284.         Windows_Interrupt(100);
  285.  
  286.         // Get white frame
  287.         _fmemcpy(training_set[i].bv, training_set[ts.numsamples * 3].bv, width);
  288.         des[0] = 0;        // want 0 output
  289.         desired[i] = *(bv_pack(des,1));
  290.  
  291.         for (WORD j = 0; j < numbits; j++)
  292.         {
  293.             bv_set(RANDOM(length), &(training_set[i]), RANDOM(2));
  294.         }
  295.  
  296.         numdone ++;
  297.         sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
  298.         TrainPct->SetText(szBuffer);
  299.     }
  300.  
  301.     // Now reinforce on a black frame
  302.  
  303.     if (!(shutdown || stop))
  304.     {
  305.         A[0]->GetBits(training_set[ts.numsamples * 4].bv);
  306.         des[0] = 0;
  307.         desired[ts.numsamples * 4] = *(bv_pack(des,1));
  308.  
  309.         for (WORD j = 0; j < length; j++)
  310.         {
  311.             bv_set(j, &(training_set[ts.numsamples * 4]), 0);
  312.         }
  313.         numdone++;
  314.     }
  315.  
  316.     for (i = (ts.numsamples * 4) + 1; i < (ts.numsamples * 5); i++)
  317.     {
  318.         if (shutdown || stop) break;
  319.  
  320.         Windows_Interrupt(100);
  321.  
  322.         // Get black frame
  323.         _fmemcpy(training_set[i].bv, training_set[ts.numsamples * 4].bv, width);
  324.         des[0] = 0;        // want 0 output
  325.         desired[i] = *(bv_pack(des,1));
  326.  
  327.         for (WORD j = 0; j < numbits; j++)
  328.         {
  329.             bv_set(RANDOM(length), &(training_set[i]), RANDOM(2));
  330.         }
  331.         numdone ++;
  332.         sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
  333.         TrainPct->SetText(szBuffer);
  334.     }
  335.  
  336.     TrainSet->ShutDownWindow();
  337.  
  338.     // Train tree
  339.  
  340.     for (i = 0; i < ts.voters; i++)
  341.     {
  342.         if (shutdown || stop) break;
  343.  
  344.         char szBuf[80];
  345.         LPATREE atree;
  346.         sprintf(szBuf,"Now training tree %d...", i + 1);
  347.         Status->SetText(szBuf);
  348.         EnableWindow(Stop->HWindow, FALSE);
  349.  
  350.         atree = atree_create(length,ts.treesize);
  351.         int result = atree_train(atree, training_set, desired, 0, numsamples,
  352.                                                          ts.mincorrect / 100 * numsamples,
  353.                                                          ts.maxepochs, 1);
  354.         if (result != -1)
  355.         {
  356.             atree_fold(atree);
  357.             atree_write(ts.stream, atree);
  358.         }
  359.         else
  360.         {
  361.             stop = TRUE;
  362.         }
  363.         atree_free(atree);
  364.         EnableWindow(Stop->HWindow, TRUE);
  365.     }
  366.  
  367.     Status->SetText("ALN Demo - Light flashes on under character ALN detects");
  368.  
  369.     for (i = 0; i < 24; i++)
  370.     {
  371.         delete A[i];
  372.         delete L[i];
  373.         delete N[i];
  374.     }
  375.  
  376.     if (shutdown) return;
  377.  
  378.     // if shutdown is TRUE during training, then an exit has been requested
  379.     // we don't need to free the memory here, since Borland's memory
  380.     // manager will do that
  381.  
  382.     for(WORD j = 0; j < numsamples; j++)
  383.     {
  384.         farfree(training_set[j].bv);
  385.         if (desired[j].bv != NULL)
  386.         {
  387.             farfree(desired[j].bv);
  388.         }
  389.     }
  390.  
  391.     farfree(training_set);
  392.     farfree(desired);
  393. }
  394.  
  395. void
  396. TOcr::OcrTrain(RTMessage Msg)
  397. {
  398.     EnableWindow(Start->HWindow, FALSE);
  399.     EnableWindow(Stop->HWindow, TRUE);
  400.     EnableWindow(Train->HWindow, FALSE);
  401.     EnableWindow(Reverse->HWindow, FALSE);
  402.     EnableWindow(Reset->HWindow, FALSE);
  403.     EnableWindow(Forget->HWindow, FALSE);
  404.     EnableWindow(EditA->HWindow, FALSE);
  405.     EnableWindow(EditL->HWindow, FALSE);
  406.     EnableWindow(EditN->HWindow, FALSE);
  407.     EnableMenuItem(hSysMenu, SC_CLOSE, MF_GRAYED);
  408.  
  409.     Status->SetText("Retraining the ALN will take 15 - 30 minutes.");
  410.  
  411.     BOOL opened = FALSE;
  412.     BOOL err = TRUE;
  413.     char szBuf[80];
  414.     HBITMAP tmp;
  415.     TrainStruct ts;
  416.     struct tagTransferBuf
  417.     {
  418.         char treesize[6];
  419.         char voters[3];
  420.         char numsamples[5];
  421.         char maxepochs[6];
  422.         char mincorrect[7];
  423.         char maxrotation[5];
  424.     } tb;
  425.  
  426.     _CLASSDEF(TTrainDlg)
  427.     class TTrainDlg : public TDialog
  428.     {
  429.     public:
  430.         TTrainDlg::TTrainDlg(PTWindowsObject AParent, int ResourceId,
  431.             struct tagTransferBuf* ATransBuf)
  432.             : TDialog(AParent, ResourceId)
  433.         {
  434.             new TEdit(this, ID_TREESIZE, 6);
  435.             new TEdit(this, ID_VOTERS, 3);
  436.             new TEdit(this, ID_NUMSAMPLES, 5);
  437.             new TEdit(this, ID_MAXEPOCHS, 6);
  438.             new TEdit(this, ID_MINCORRECT, 7);
  439.             new TEdit(this, ID_MAXROTATION, 5);
  440.             TransferBuffer = ATransBuf;
  441.         }
  442.     };
  443.  
  444.     // set default training values
  445.     ts.treesize = 2048;
  446.     ts.voters = 3;
  447.     ts.numsamples = 200;
  448.     ts.maxepochs = 30;
  449.     ts.mincorrect = 99.9;
  450.     ts.maxrotation = 5;
  451.  
  452.     shutdown = FALSE;
  453.     stop = FALSE;
  454.  
  455.     while (err)
  456.     {
  457.         err = FALSE;
  458.         itoa(ts.treesize, tb.treesize, 10);
  459.         itoa(ts.voters, tb.voters, 10);
  460.         itoa(ts.numsamples, tb.numsamples, 10);
  461.         itoa(ts.maxepochs, tb.maxepochs, 10);
  462.         sprintf(tb.mincorrect, "%5.2f", ts.mincorrect);
  463.         itoa(ts.maxrotation, tb.maxrotation, 10);
  464.  
  465.         PTTrainDlg TrainDlg;
  466.         TrainDlg = new TTrainDlg(this, OCR_TRAINDLG, &tb);
  467.  
  468.         if (GetApplication()->ExecDialog(TrainDlg) == IDCANCEL)
  469.         {
  470.             stop = TRUE;
  471.             break;
  472.         }
  473.  
  474.         if ((ts.treesize = atoi(tb.treesize)) == 0)
  475.         {
  476.             err = TRUE;
  477.             BWCCMessageBox(HWindow, "Invalid Tree Size entry",
  478.                                          NULL, MB_ICONQUESTION | MB_OK);
  479.         }
  480.         if ((ts.voters = atoi(tb.voters)) == 0)
  481.         {
  482.             err = TRUE;
  483.             BWCCMessageBox(HWindow, "Invalid Voters entry",
  484.                                          NULL, MB_ICONQUESTION | MB_OK);
  485.         }
  486.         if ((ts.numsamples = atoi(tb.numsamples)) == 0)
  487.         {
  488.             err = TRUE;
  489.             BWCCMessageBox(HWindow, "Invalid Number of Samples entry",
  490.                                          NULL, MB_ICONQUESTION | MB_OK);
  491.         }
  492.         if ((ts.maxepochs = atoi(tb.maxepochs)) == 0)
  493.         {
  494.             err = TRUE;
  495.             BWCCMessageBox(HWindow, "Invalid Maximum Epochs entry",
  496.                                          NULL, MB_ICONQUESTION | MB_OK);
  497.         }
  498.         if ((ts.mincorrect = atof(tb.mincorrect)) == 0)
  499.         {
  500.             err = TRUE;
  501.             BWCCMessageBox(HWindow, "Invalid Minimum Percent Correct entry",
  502.                                          NULL, MB_ICONQUESTION | MB_OK);
  503.         }
  504.         ts.maxrotation = atoi(tb.maxrotation);
  505.     }
  506.  
  507.     if (!(shutdown || stop))
  508.     {
  509.         if ((ts.stream = fopen("ocr.tre", "w")) == NULL)
  510.         {
  511.             BWCCMessageBox(HWindow, "Can't open 'ocr.tre'", "OCR Train",
  512.                          MB_ICONEXCLAMATION | MB_OK);
  513.             exit(0);
  514.         }
  515.  
  516.         atree_init(GetApplication()->hInstance, HWindow);
  517.         fprintf(ts.stream, "%d\n", ts.voters);
  518.         opened = TRUE;
  519.     }
  520.  
  521.     if (!(shutdown || stop))
  522.     {
  523.         ts.bitmaps[0] = LetterA->GetBitmap();
  524.         ts.bitmaps[1] = LetterL->GetBitmap();
  525.         ts.bitmaps[2] = LetterN->GetBitmap();
  526.         Status->SetText("Please wait while training set is built for first character...");
  527.         train(ts);
  528.     }
  529.     if (!(shutdown || stop))
  530.     {
  531.         tmp = ts.bitmaps[0];
  532.         ts.bitmaps[0] = ts.bitmaps[1];
  533.         ts.bitmaps[1] = tmp;
  534.         Status->SetText("Please wait while training set is built for second character...");
  535.         train(ts);
  536.     }
  537.     if (!(shutdown || stop))
  538.     {
  539.         tmp = ts.bitmaps[0];
  540.         ts.bitmaps[0] = ts.bitmaps[2];
  541.         ts.bitmaps[2] = tmp;
  542.         Status->SetText("Please wait while training set is built for third character...");
  543.         train(ts);
  544.     }
  545.  
  546.     if (opened)
  547.     {
  548.         fclose(ts.stream);
  549.         atree_quit();
  550.     }
  551.  
  552.     if ((shutdown || stop) && opened) remove("ocr.tre");
  553.  
  554.     EnableWindow(Start->HWindow, TRUE);
  555.     EnableWindow(Stop->HWindow, FALSE);
  556.     EnableWindow(Train->HWindow, TRUE);
  557.     EnableWindow(Reverse->HWindow, TRUE);
  558.     EnableWindow(Reset->HWindow, TRUE);
  559.     EnableWindow(Forget->HWindow, TRUE);
  560.     EnableWindow(EditA->HWindow, TRUE);
  561.     EnableWindow(EditL->HWindow, TRUE);
  562.     EnableWindow(EditN->HWindow, TRUE);
  563.     EnableMenuItem(hSysMenu, SC_CLOSE, MF_ENABLED);
  564. }
  565.  
  566.  
  567.